package track_formats

import (
	"time"

	"github.com/pion/rtp"
	"gogs.smarteye.com/servere/gobvrtp/encoder"
	"gogs.smarteye.com/servere/gobvrtp/track"
)

type G711UTrack struct {
	AudioTrack

	encoder *encoder.AudioEncoder
	decoder *encoder.AudioDecoder
}

func NewG711UTrack() *G711UTrack {

	c := &G711UTrack{}

	param := c.CtlParma()
	param.SetPayloadType(8)
	param.SetCodec(track.CodecIdG711U)
	param.SetClockRate(8000)
	param.SetOnReadRTPFunc(c.onRTP)

	return c
}

func (c *G711UTrack) SetSampleRate(sampleRate int) *G711UTrack {
	c.CtlParma().SetClockRate(sampleRate)
	return c
}

// RTPMap implements Format.
func (c *G711UTrack) RTPMap() string {
	return "PCMU/8000"
}

// FMTP implements Format.
func (c *G711UTrack) FMTP() map[string]string {
	return nil
}

func (c *G711UTrack) WritePacket(t time.Time, data []byte) error {
	param := c.CtlParma()

	if c.encoder == nil {
		// 初始化编码器
		e := &encoder.AudioEncoder{
			PayloadType:           c.PayloadType(),
			SSRC:                  ToPtr(c.SSRC()),
			InitialSequenceNumber: ToPtr(param.InitialSequenceNumber),
			PayloadMaxSize:        param.PayloadMaxSize,
		}

		_ = e.Init()
		c.encoder = e
	}

	packet, err := c.encoder.Encode(data)
	if err != nil {
		return err
	}

	timestamp, _ := c.CtlParma().RtpTimeEncode(t)
	packet.Timestamp = timestamp

	if err = c.WriteRTP(packet); err != nil {
		return err
	}

	return nil
}

func (c *G711UTrack) onRTP(_ track.Track, pkt *rtp.Packet) {
	packets, _ := c.Detector(pkt)

	if c.decoder == nil {
		// 初始化解码器
		decoder := &encoder.AudioDecoder{}
		_ = decoder.Init()
		c.decoder = decoder
	}

	for _, packet := range packets {
		if data, err := c.decoder.Decode(packet); err == nil {
			c.onFrame(packet, data)
		}
	}

}

func init() {
	RegisterTrack(track.CodecIdG711U, func() track.Track {
		return NewG711UTrack()
	})
}
